//////////////////////////////////////////////
// MaybeSingletonClassWrapper.h
//
//////////////////////////////////////////////

/// Defines / Macros -------------------------

#pragma once

/// Includes ---------------------------------

// nkAstraeus
#include "../../../Dll/DllDefines.h"

// nkScripts
#include <NilkinsScripts/Environments/Functions/Function.h>

#include <NilkinsScripts/Environments/UserTypes/UserType.h>

/// Class ------------------------------------

namespace nkAstraeus::nkCommonWrap
{
	class DLL_ASTRAEUS_EXPORT MaybeSingletonClassWrapper final
	{
		public :

			// Updates
			template <typename T>
			static void inherit (nkScripts::UserType* childType)
			{
				{
					nkScripts::Function* method = childType->addStaticMethod("getInstance") ;
					method->setFunction([childType] (const nkScripts::DataStack& stack) -> nkScripts::OutputValue {return getInstance<T>(childType->getFullName(), stack) ;}) ;
				}

				{
					nkScripts::Function* method = childType->addMethod("isTheSingletonInstance") ;
					method->setFunction(&isTheSingletonInstance<T>) ;
				}
			}

		private :

			// Underlying methods
			template <typename T>
			static nkScripts::OutputValue getInstance (nkMemory::StringView userTypeName, const nkScripts::DataStack& stack)
			{
				return nkScripts::OutputValue(T::getInstance(), userTypeName, false) ;
			}

			template <typename T>
			static nkScripts::OutputValue isTheSingletonInstance (const nkScripts::DataStack& stack)
			{
				T* ptr = (T*)stack[0]._valUser._userData ;
				return nkScripts::OutputValue(ptr->isTheSingletonInstance()) ;
			}
	} ;
}